
use std::{fs::create_dir_all, path::{absolute, Path, PathBuf}};

use chrono::Local;

use crate::{logs::WTASK_BASIC_FILE_NAME, error::{WError, WResult}};

use crate::machine::get_home_dir;


pub fn get_wtask_root_dir() -> PathBuf {
    let dir = if let Ok(dir) = std::env::var("WTASK_ROOT") {
        PathBuf::from(dir)
    } else {
        get_home_dir().join(WTASK_BASIC_FILE_NAME)
    };
    if !dir.exists() {
        create_dir_all(&dir).expect("wTask root dir error");
    }
    dir
}


pub fn get_wtask_data_dir(tag: &str, use_date: bool) -> WResult<PathBuf> {
    let dir = get_wtask_root_dir();
    let mut dir = dir.join(tag);
    if use_date {
        dir = dir.join(Local::now().format("%Y_%m_%d").to_string());
    }
    if !dir.is_absolute() {
        dir = absolute(dir)?;
    }
    if !dir.exists() {
        create_dir_all(&dir)?;
    }
    Ok(dir)
}


pub fn get_wtask_result_dir(id: &str) -> WResult<Option<PathBuf>> {
    let dir_data = get_wtask_data_dir("result", false)?;
    let res = dir_data.read_dir()?.map(| v |{
        v.unwrap().path().join(id)
    }).find(| v | v.exists());
    Ok(res)
}


pub fn get_wtask_file_res(file: &Path) -> WResult<PathBuf> {
    let dir = get_wtask_data_dir("file", true)?;
    let file_basename = file.file_name().unwrap().to_str().unwrap();
    Ok(dir.join(file_basename))
}


pub fn get_wtask_app_dir(app: &str, version: &str) -> WResult<PathBuf> {
    let version_filter = if version.eq("latest") {
        ""
    } else {
        version
    };
    let prefix = format!("{app}.{version_filter}");
    let dir_task = get_wtask_data_dir("task", false)?;
    let mut apps = dir_task.read_dir().unwrap().map(| v | {
        v.unwrap().path().file_name().unwrap().to_string_lossy().to_string()
    }).filter(| v | {
        v.starts_with(&prefix)
    }).collect::<Vec<_>>();
    apps.sort();

    if apps.is_empty() {
        return Err(WError::Empty);
    }
    let app = apps.last().unwrap();
    let app_path = dir_task.join(app);
    Ok(app_path)
}

